//
// Created by zhouyi on 2019-11-29.
//

#ifndef TESTFFMPEG_BASECHANNEL_H
#define TESTFFMPEG_BASECHANNEL_H

extern "C" {
#include <libavcodec/avcodec.h>
};

#include "JavaCallHelper.h"
#include "safe_queue.h"

class BaseChannel {

protected:
    BaseChannel(int channelId, JavaCallHelper *helper, AVCodecContext *avCodecContext, const AVRational &base)
            : channelId(channelId), helper(helper), avCodecContext(avCodecContext), time_base(base) {
        pkt_queue.setReleaseHandle(releaseAvPacket);
        frame_queue.setReleaseHandle(releaseAvFrame);
    };


    virtual  ~BaseChannel() {
        if (avCodecContext) {
            avcodec_close(avCodecContext);
            avcodec_free_context(&avCodecContext);
            avCodecContext = 0;
        }
        pkt_queue.clear();
        frame_queue.clear();
    };

    // 这种形式纯虚函数
    virtual void play() = 0;

    virtual void stop() = 0;

    virtual void decode() = 0;


    void setEnable(bool enable) {
        pkt_queue.setEnable(enable);
        frame_queue.setEnable(enable);
    }


    static void releaseAvPacket(AVPacket *&avPacket) {
        if (avPacket) {
            av_packet_free(&avPacket);
            avPacket = nullptr;
        }
    }


    static void releaseAvFrame(AVFrame *&avFrame) {
        if (avFrame) {
            av_frame_free(&avFrame);
            avFrame = nullptr;
        }
    }

public:
    int channelId;
    JavaCallHelper *helper;
    AVCodecContext *avCodecContext;
    AVRational time_base;

    SafeQueue<AVPacket *> pkt_queue;
    SafeQueue<AVFrame *> frame_queue;


};


#endif //TESTFFMPEG_BASECHANNEL_H
